﻿/* ######################################## *\
 * ### Copyright (C) 2009 AJ Ravindiran ### *
 * ### HTTP://THEAJ.NET/ <AJ@THEAJ.NET> ### *
\* ######################################## */
using System;
using System.IO;
using System.Collections.Generic;

namespace AJRavindiran.Jolt.Utilities
{
    public class Configuration
    {
        #region Fields
        /// <summary>
        /// Storage for all the loaded values.
        /// </summary>
        private Dictionary<string, string> mConfigContent = new Dictionary<string, string>();
        #endregion

        #region Properties
        /// <summary>
        /// Gets or sets the configuration value as string for a given key.
        /// </summary>
        /// <param name="key">The key (string) to get or set the value string of.</param>
        public string this[string key]
        {
            get
            {
                return this.GetValue(key);
            }
            set
            {
                this.SetValue(key, value);
            }
        }
        #endregion

        #region Methods
        /// <summary>
        /// Returns the configuration value string of a given key. A blank string is returned if the configuration key is not defined.
        /// </summary>
        /// <param name="key">The configuration key as a string.</param>
        /// <returns>The configuration value of a given key as a string.</returns>
        public string GetValue(string key)
        {
            if (!mConfigContent.ContainsKey(key))
                return "";

            return mConfigContent[key];
        }

        public void SetValue(string sKey, string value)
        {
            if (mConfigContent.ContainsKey(sKey))
                mConfigContent[sKey] = value;
            else
                mConfigContent.Add(sKey, value);
        }

        public bool TryParseInt32(string field, out int i)
        {
            bool success = int.TryParse(this[field], out i);
            if (!success)
                JoltEnvironment.GetLogger().WriteConfigurationParseError(field);

            return success;
        }

        public bool TryParseUInt32(string field, out uint i)
        {
            bool success = uint.TryParse(this[field], out i);
            if (!success)
                JoltEnvironment.GetLogger().WriteConfigurationParseError(field);

            return success;
        }

        public int TryParseInt32(string field)
        {
            int i = 0; TryParseInt32(field, out i);
            return i;
        }

        public uint TryParseUInt32(string field)
        {
            uint i = 0; TryParseUInt32(field, out i);
            return i;
        }

        /// <summary>
        /// Loads a ConfigurationModule from a file at a given path.
        /// </summary>
        /// <param name="path">The path of the configuration file to load.</param>
        /// <returns>ConfigurationModule holding the loaded configurations.</returns>
        public static Configuration LoadFromFile(string path)
        {
            if (!File.Exists(path))
                throw new FileNotFoundException("File at path \"" + path + "\" does not exist.");

            Configuration config = new Configuration();
            using (StreamReader reader = new StreamReader(path))
            {
                string line = null;
                while ((line = reader.ReadLine()) != null)
                {
                    if (line.Length == 0 || line[0] == '#')
                        continue; // This line is empty/a comment

                    int indexOfDelimiter = line.IndexOf('=');
                    if (indexOfDelimiter != -1)
                    {
                        string key = line.Substring(0, indexOfDelimiter);
                        if (!config.mConfigContent.ContainsKey(key))
                        {
                            string value = line.Substring(indexOfDelimiter + 1);
                            config.mConfigContent.Add(key, value);
                        }
                    }
                }
                reader.Close();
            }
            return config;
        }
        #endregion
    }
}
